<template>
  <div class="cropper-content">
    <label :for="id"><slot /></label>
    <input
      ref="fileInput"
      type="file"
      :id="id"
      style="position: absolute; clip: rect(0 0 0 0)"
      @change="selectImg($event)"
      accept="image/*"
      capture="camera"
    />
    <Popup
      v-model="isShow"
      position="bottom"
      :style="{ height: '100%' }"
      :closeable="true"
      :close-on-click-overlay="false"
      :lazy-render="true"
    >
      <div class="cropper-box">
        <div class="cropper">
          <vue-cropper
            ref="cropper"
            :img="option.img"
            :outputSize="option.outputSize"
            :outputType="option.outputType"
            :info="option.info"
            :canScale="option.canScale"
            :autoCrop="option.autoCrop"
            :autoCropWidth="option.autoCropWidth"
            :autoCropHeight="option.autoCropHeight"
            :fixed="option.fixed"
            :fixedNumber="option.fixedNumber"
            :full="option.full"
            :fixedBox="option.fixedBox"
            :canMove="option.canMove"
            :canMoveBox="option.canMoveBox"
            :original="option.original"
            :centerBox="option.centerBox"
            :height="option.height"
            :infoTrue="option.infoTrue"
            :maxImgSize="option.maxImgSize"
            :enlarge="option.enlarge"
            :mode="option.mode"
            @realTime="realTime"
            @imgLoad="imgLoad"
          >
          </vue-cropper>
        </div>
        <!--预览效果图-->
        <div class="show-preview" v-if="preview">
          <div :style="previews.div" class="preview">
            <img :src="previews.url" :style="previews.img" />
          </div>
        </div>
        <!--底部操作工具按钮-->
        <div class="footer-btn">
          <div class="scope-btn">
            <Button size="mini" @click="moveXreduce()">← 左移</Button>
            <Button size="mini" @click="moveXadd()">→ 右移</Button>
            <Button size="mini" @click="moveYreduce()">↑ 上移</Button>
            <Button size="mini" @click="moveYadd()">↓ 下移</Button>
          </div>
          <div class="scope-btn">
            <!-- <label
            class="btn van-button van-button--default van-button--mini"
            :for="id"
          >重选</label> -->
            <!-- <input
              ref="fileInput"
              type="file"
              :id="id"
              style="position: absolute; clip: rect(0 0 0 0)"
              @change="selectImg($event)"
              accept="image/*"
              capture="camera"
            /> -->

            <Button size="mini" @click="changeScale(1)">+ 放大</Button>
            <Button size="mini" @click="changeScale(-1)">- 缩小</Button>
            <Button size="mini" @click="rotateLeft">↺ 左旋转</Button>
            <Button size="mini" @click="rotateRight">↻ 右旋转</Button>
          </div>
          <Button type="primary" class="upload" block @click="uploadImg"
            >裁剪并上传</Button
          >
          <!-- <div class="upload-btn">
          <el-button size="mini" type="success" @click="uploadImg('blob')"
            >上传封面 <i class="el-icon-upload"></i
          ></el-button>
        </div> -->
        </div>
      </div>
    </Popup>
  </div>
</template>

<script>
import { VueCropper } from "vue-cropper";
import { Button, Popup } from "vant";
import axios from "axios";
export default {
  name: "CropperImage",
  components: {
    VueCropper,
    Button,
    Popup,
  },
  props: {
    params: {
      default: () => {},
    },
    preview: {
      default: false,
    },
    url: {
      default: "",
    },
  },
  watch: {
    isShow(val) {
      if (val) {
        this.$nextTick(() => {
          console.log(this.$refs.cropper);
        });
      }
    },
  },
  data() {
    let width = (window.screen.width * (3 / 2)) / 1.65;
    return {
      id: "",
      name: this.Name,
      previews: {},
      resData: "",
      isShow: false,
      timeOutEvent: null,
      timeEvent: null,
      option: {
        img: "", //裁剪图片的地址
        outputSize: 0.75, //裁剪生成图片的质量(可选0.1 - 1)
        outputType: "jpeg", //裁剪生成图片的格式（jpeg || png || webp）
        info: false, //图片大小信息
        canScale: true, //图片是否允许滚轮缩放
        autoCrop: true, //是否默认生成截图框
        autoCropWidth: width, //默认生成截图框宽度
        autoCropHeight: width / (4 / 3), //默认生成截图框高度
        fixed: true, //是否开启截图框宽高固定比例
        fixedNumber: [4, 3], //截图框的宽高比例
        full: false, //false按原比例裁切图片，不失真
        fixedBox: true, //固定截图框大小，不允许改变
        canMove: false, //上传图片是否可以移动
        canMoveBox: true, //截图框能否拖动
        original: false, //上传图片按照原始比例渲染
        centerBox: false, //截图框是否被限制在图片里面
        height: true, //是否按照设备的dpr 输出等比例图片
        infoTrue: false, //true为展示真实输出图片宽高，false展示看到的截图框宽高
        maxImgSize: 3000, //限制图片最大宽度和高度
        enlarge: 1024 / width, //图片根据截图框输出比例倍数
        mode: "375px 667px", //图片默认渲染方式
      },
    };
  },
  created() {
    this.id = this.$uuid();
  },
  methods: {
    //初始化函数
    imgLoad(msg) {
      console.log("工具初始化函数=====" + msg);
    },
    //图片缩放
    changeScale(num) {
      num = num || 1;
      this.$refs.cropper.changeScale(num);
    },
    //向左旋转
    rotateLeft() {
      this.$refs.cropper.rotateLeft();
    },
    //向右旋转
    rotateRight() {
      this.$refs.cropper.rotateRight();
    },
    moveXreduce() {
      this.$set(this.$refs.cropper, "x", this.$refs.cropper.x - 20);
    },
    moveXadd() {
      this.$set(this.$refs.cropper, "x", this.$refs.cropper.x + 20);
    },
    moveYreduce() {
      this.$set(this.$refs.cropper, "y", this.$refs.cropper.y - 20);
    },
    moveYadd() {
      this.$set(this.$refs.cropper, "y", this.$refs.cropper.y + 20);
    },
    //实时预览函数
    realTime(data) {
      this.previews = data;
    },
    //选择图片
    selectImg(e) {
      let file = e.target.files[0];
      if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) {
        this.$toast.fail("图片类型要求：jpeg、jpg、png");
        return false;
      }
      //转化为blob
      let reader = new FileReader();
      reader.onload = (e) => {
        let data;
        if (typeof e.target.result === "object") {
          data = window.URL.createObjectURL(new Blob([e.target.result]));
        } else {
          data = e.target.result;
        }
        this.isShow = true;
        this.option.img = data;
      };
      this.$refs.fileInput.value = "";
      //转化为base64
      reader.readAsDataURL(file);
    },
    uploadFile() {
      this.$nextTick(() => {
        console.log(this.$refs.cropper);
        this.$refs.fileInput.click();
      });
    },
    //上传图片
    uploadImg(type = "base64") {
      //获取截图的blob数据
      this.$refs.cropper.getCropBlob(async (data) => {
        let formData = new FormData();
        this.$getImageBase64(data).then(async (base64) => {
          let data = null;
          if (type === "blob") {
            formData.append("file", data, "DX.jpg");
            //调用axios上传
            data = await axios.post(this.url, formData);
          } else {
            data = await axios.post(this.url, {
              img: base64,
              ...this.params,
            });
          }
          let res = data.res;
          if (res.code === 200) {
            this.$toast.success("上传成功！");
            let imgInfo = {
              name: this.Name,
              url: base64,
              blob: data,
            };
            this.$emit("uploadImgSuccess", imgInfo);
          }
        });
      });
    }, //长按事件（起始）
    gtouchstart(fn) {
      var self = this;
      this.timeOutEvent = setTimeout(function () {
        self.longPress(fn);
      }, 500); //这里设置定时器，定义长按500毫秒触发长按事件
      return false;
    },
    //手释放，如果在500毫秒内就释放，则取消长按事件，此时可以执行onclick应该执行的事件
    showDeleteButton() {
      clearTimeout(this.timeOutEvent); //清除定时器
      if (this.timeOutEvent != 0) {
        //这里写要执行的内容（如onclick事件）
        console.log("点击但未长按");
      }
      return false;
    },
    //如果手指有移动，则取消所有事件，此时说明用户只是要移动而不是长按
    gtouchmove() {
      clearTimeout(this.timeOutEvent); //清除定时器
      clearInterval(this.timeEvent); //清除定时器
      this.timeOutEvent = 0;
    },
    //真正长按后应该执行的内容
    longPress(fn) {
      clearInterval(this.timeEvent); //清除定时器
      this.timeOutEvent = 0;
      //执行长按要执行的内容，如弹出菜单
      this.timeEvent = setInterval(() => fn(), 30);
      console.log("长按");
    },
  },
};
</script>

<style scoped lang="scss">
.cropper-content {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
.cropper-box {
  flex: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
}
.cropper {
  padding: 16px;
  width: auto;
  height: calc(100vh - 32px - 155px);
}

.show-preview {
  flex: 1;
  -webkit-flex: 1;
  display: flex;
  display: -webkit-flex;
  justify-content: center;
}
.preview {
  overflow: hidden;
  border: 1px solid #67c23a;
  background: #cccccc;
}
.footer-btn {
  margin-top: auto;
  .scope-btn {
    display: flex;
    display: -webkit-flex;
    justify-content: flex-end;
    margin: 0 15px;
    margin-bottom: 15px;
    & > * {
      flex: 1;
      & + * {
        margin-left: 0.5em;
      }
    }
  }
}
.upload {
  margin-top: auto;
}
.upload-btn {
  flex: 1;
  -webkit-flex: 1;
  display: flex;
  display: -webkit-flex;
  justify-content: center;
}
.scope-btn {
  display: flex;
  display: -webkit-flex;
  justify-content: space-between;
}
.btn {
  outline: none;
  display: inline-block;
  display: flex;
  align-items: center;
  justify-content: center;
  // line-height: 1;
  // white-space: nowrap;
  // cursor: pointer;
  // -webkit-appearance: none;
  // text-align: center;
  // -webkit-box-sizing: border-box;
  // box-sizing: border-box;
  // outline: 0;
  // -webkit-transition: 0.1s;
  // transition: 0.1s;
  // font-weight: 500;
  // padding: 8px 15px;
  // font-size: 12px;
  // border-radius: 3px;
  // color: #fff;
  // background-color: #409eff;
  // border-color: #409eff;
  // margin-right: 10px;
}
.cropper-crop-box {
  border: 10px solid #39f;
}
</style>
